package com.xiyu.service.service.setting;

import com.xiyu.service.vo.setting.businessField.BusinessFieldGetByModuleOutput;
import com.xiyu.service.enums.business.SettingBusinessModuleEnum;
import com.xiyu.service.util.common.CommonUtils;
import com.xiyu.service.model.setting.business.SettingBusinessFieldProps;
import com.xiyu.service.model.setting.business.SettingBusinessFieldDraft;
import com.xiyu.service.model.setting.business.SettingBusinessFieldOption;
import com.xiyu.service.repository.setting.business.SettingBusinessFieldOptionRepository;
import com.xiyu.service.vo.setting.businessField.BusinessFieldUpdateInput;
import com.xiyu.service.vo.setting.businessField.BusinessFieldSingleGetOutput;
import com.xiyu.service.vo.setting.businessField.BusinessFieldGetOptionByFieldIdOutput;
import com.xiyu.service.model.setting.business.SettingBusinessField;
import com.xiyu.service.repository.setting.business.SettingBusinessFieldRepository;
import com.xiyu.service.vo.setting.businessField.BusinessFieldListQueryOutput;
import com.xiyu.service.vo.setting.businessField.BusinessFieldListQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import org.springframework.transaction.annotation.Transactional;

import java.util.stream.Collectors;

import com.xiyu.service.util.entity.EntityUtils;
import org.babyfish.jimmer.DraftObjects;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.setting.BusinessFieldConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.setting.BusinessFieldErrorCode.*;

/**
 * 业务字段 Service 实现类
 */
@Service
@Validated
public class BusinessFieldServiceImpl implements BusinessFieldService {

    @Resource
    private SettingBusinessFieldOptionRepository settingBusinessFieldOptionRepository;

    @Resource
    private SettingBusinessFieldRepository settingBusinessFieldRepository;




    @Override
    public List<BusinessFieldListQueryOutput> listQuery(BusinessFieldListQueryInput inputVO) {
        List<SettingBusinessField> listSettingBusinessField = settingBusinessFieldRepository.listQuery(inputVO);
        return BusinessFieldConvert.INSTANCE.listQueryOutputConvert(listSettingBusinessField);

    }

    @Override
    public List<BusinessFieldGetOptionByFieldIdOutput> getOptionByFieldId(Long id) {
        return BusinessFieldConvert.INSTANCE.getOptionByFieldIdOutputConvert(settingBusinessFieldOptionRepository.findByBusinessFieldId(id));
    }

    @Override
    public BusinessFieldSingleGetOutput singleGet(Long id) {
        Optional<SettingBusinessField> optionSettingBusinessField = settingBusinessFieldRepository.findDetailById(id);
        if(optionSettingBusinessField.isEmpty()){
            throw exception(SETTING_BUSINESS_FIELD_NOT_EXIST);
        }
        return BusinessFieldConvert.INSTANCE.singleGetOutputConvert(optionSettingBusinessField.get());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(BusinessFieldUpdateInput inputVO) {
        Optional<SettingBusinessField> optionalOldSettingBusinessField = settingBusinessFieldRepository.findById(inputVO.getId());
        if(optionalOldSettingBusinessField.isEmpty()){
            throw exception(SETTING_BUSINESS_FIELD_NOT_EXIST);
        }

        Optional<SettingBusinessField> optionalDuplicateField = settingBusinessFieldRepository.findByBusinessModuleAndFieldName(inputVO.getBusinessModule(), inputVO.getFieldName());
        if(optionalDuplicateField.isPresent() && optionalDuplicateField.get().id() != inputVO.getId()){
            throw exception(SETTING_BUSINESS_FIELD_DUPLICATE, optionalDuplicateField.get().businessModule().equals(SettingBusinessModuleEnum.CUSTOMER.getValue()) ? "客户" : "客户联系人", optionalDuplicateField.get().showName()) ;
        }

        for(BusinessFieldUpdateInput.option option : inputVO.getOptions()){
            if(Objects.equals(option.getOperateType(), "delete")){
                Optional<SettingBusinessFieldOption> optionalDeleteSettingBusinessFieldOption = settingBusinessFieldOptionRepository.findById(option.getId());
                if(optionalDeleteSettingBusinessFieldOption.isEmpty()){
                    throw exception(SETTING_BUSINESS_FIELD_OPTION_NOT_EXIST);
                }
                isNotDeleteOption(option.getId());
                settingBusinessFieldOptionRepository.deleteById(option.getId());
            }else if(Objects.equals(option.getOperateType(), "new")){
                if(option.getName().isEmpty()){
                    throw exception(SETTING_BUSINESS_FIELD_OPTION_NOT_EMPTY);
                }
                Optional<SettingBusinessFieldOption> optionalDuplicateOption = settingBusinessFieldOptionRepository.findByBusinessFieldIdAndName(option.getBusinessFieldId(), option.getName());
                if(optionalDuplicateOption.isPresent() && optionalDuplicateOption.get().id() != option.getId()){
                    throw exception(SETTING_BUSINESS_FIELD_OPTION_DUPLICATE, optionalDuplicateOption.get().name());
                }
                // 前端为了实现拖拽功能，设置了id，后端要设置为null，使用自增键
                option.setId(null);
                option.setSort(0L);

                SettingBusinessFieldOption newSettingBusinessFieldOption = BusinessFieldConvert.INSTANCE.updateInputConvert(option);
                SettingBusinessFieldOption newOption = settingBusinessFieldOptionRepository.insert(newSettingBusinessFieldOption);
                settingBusinessFieldOptionRepository.updateSort(newOption.id(), newOption.id());
                // 为后面重新排序使用
                option.setId(newOption.id()).setSort(newOption.id());
            }else{
                if(option.getName().isEmpty()){
                    throw exception(SETTING_BUSINESS_FIELD_OPTION_NOT_EMPTY);
                }
                Optional<SettingBusinessFieldOption> optionalOldSettingBusinessFieldOption = settingBusinessFieldOptionRepository.findById(option.getId());
                if(optionalOldSettingBusinessFieldOption.isEmpty()) {
                    throw exception(SETTING_BUSINESS_FIELD_OPTION_NOT_EXIST);
                }
                SettingBusinessFieldOption updateSettingBusinessFieldOption = BusinessFieldConvert.INSTANCE.updateInputConvert(option);
                if (!EntityUtils.isEquals(optionalOldSettingBusinessFieldOption.get(), updateSettingBusinessFieldOption))
                    settingBusinessFieldOptionRepository.update(updateSettingBusinessFieldOption);
            }
        }
        // 重新排序
        List<SettingBusinessFieldOption> oldOption = settingBusinessFieldOptionRepository.findByBusinessFieldId(inputVO.getId());
        List<BusinessFieldUpdateInput.option> newOptions = inputVO.getOptions().stream().filter(option -> !Objects.equals(option.getOperateType(), "delete")).collect(Collectors.toList());
        int index = 0;
        for(BusinessFieldUpdateInput.option option : newOptions){
            if(!option.getSort().equals(oldOption.get(index).sort())){
                settingBusinessFieldOptionRepository.updateSort(option.getId(), oldOption.get(index).sort());
            }
            index++;
        }

        SettingBusinessField updateSettingBusinessField = BusinessFieldConvert.INSTANCE.updateInputConvert(inputVO);
        updateSettingBusinessField = SettingBusinessFieldDraft.$.produce(updateSettingBusinessField, draft -> DraftObjects.unload(draft, SettingBusinessFieldProps.OPTIONS));
        if (!EntityUtils.isEquals(optionalOldSettingBusinessField.get(), updateSettingBusinessField))
            settingBusinessFieldRepository.update(updateSettingBusinessField);
        return true;
    }

    private void isNotDeleteOption(Long optionId){
        Long dealOptionId = getStateDealOptionId();
        if(Objects.equals(dealOptionId, optionId)){
            throw exception(SETTING_BUSINESS_FIELD_NOT_DELETE, "成交状态");
        }
        Long resignOptionId = getWorkStateResignOptionId();
        if(Objects.equals(resignOptionId, optionId)){
            throw exception(SETTING_BUSINESS_FIELD_NOT_DELETE, "离职工作状态");
        }
    }

    @Override
    public List<BusinessFieldGetByModuleOutput> getByModule(Integer businessModule) {
        return BusinessFieldConvert.INSTANCE.getByModuleOutputConvert(settingBusinessFieldRepository.findByModule(businessModule));
    }

    @Override
    public Long getStateDealOptionId(){
        SettingBusinessField stateField = settingBusinessFieldRepository.findByBusinessModuleAndFieldName(SettingBusinessModuleEnum.CUSTOMER.getValue(), "state").orElse(null);
        if(stateField == null){
            throw exception(SETTING_BUSINESS_FIELD_EMPTY, "状态");
        }
        SettingBusinessFieldOption stateOption = settingBusinessFieldOptionRepository.findByBusinessFieldIdAndName(stateField.id(), "成交").orElse(null);
        if(stateOption == null){
            throw exception(SETTING_BUSINESS_FIELD_OPTION_EMPTY, "成交");
        }
        return stateOption.id();
    }

    @Override
    public Long getWorkStateResignOptionId() {
        SettingBusinessField workStateField = settingBusinessFieldRepository.findByBusinessModuleAndFieldName(SettingBusinessModuleEnum.CUSTOMER_CONTACT.getValue(), "work_state").orElse(null);
        if(workStateField == null){
            throw exception(SETTING_BUSINESS_FIELD_EMPTY, "工作状态");
        }
        SettingBusinessFieldOption workStateOption = settingBusinessFieldOptionRepository.findByBusinessFieldIdAndName(workStateField.id(), "离职").orElse(null);
        if(workStateOption == null){
            throw exception(SETTING_BUSINESS_FIELD_OPTION_EMPTY, "离职");
        }
        return workStateOption.id();
    }

}
